package bancosys.tec.persist.hibernate.impl.annotations;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import jmine.tec.utils.debug.impl.DebugRuntimeFactory;
import bancosys.tec.persist.hibernate.DirtyAwareSession;

/**
 * Tracker de sessão
 * 
 * @author takeshi.fukushima
 */
public final class SessionTracker {

    private final Map<Object, String> openSessions = new ConcurrentHashMap<Object, String>();

    private static final SessionTracker INSTANCE = new SessionTracker();

    /**
     * C'tor
     */
    private SessionTracker() {
        DebugRuntimeFactory.getInstance().exposeAsJMX("hibernateSessionTracker", this);
    }

    /**
     * @return the sessionTracker instance
     */
    public static SessionTracker getInstance() {
        return INSTANCE;
    }

    /**
     * Registra a abertura de uma sessão
     * 
     * @param session session
     */
    public void registerOpenSession(DirtyAwareSession session) {
        if (DebugRuntimeFactory.ENABLED) {
            this.openSessions.put(session, DebugRuntimeFactory.getCurrentThreadStack());
        }
    }

    /**
     * Remove a sessão do mapa de sessões abertas
     * 
     * @param session a session a ser removida
     */
    public void sessionClosed(DirtyAwareSession session) {
        if (DebugRuntimeFactory.ENABLED) {
            this.openSessions.remove(session);
        }
    }

    /**
     * @return o número de sessions abertas
     */
    public int getNumberOfSessions() {
        return this.openSessions.size();
    }

    /**
     * Limpa a lista de sessões
     */
    public void clear() {
        this.openSessions.clear();
    }

    /**
     * @return o array de sessões abertas
     */
    public String[] openSessionsAsArray() {
        return this.openSessions.values().toArray(new String[this.openSessions.size()]);
    }

}
